package com.msoe.client.panels.eventhandlers;

import java.util.HashMap;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.Widget;
import com.msoe.client.Server;
import com.msoe.client.dataaccess.SimpleUser;
import com.msoe.client.panels.Login;
import com.msoe.client.panels.MessageBox;
import com.msoe.client.panels.PanelMap;

public class LoginEventHandler implements ClickListener, KeyboardListener{
	
	private Login log;
	
	public LoginEventHandler(Login login){
		log = login;
	}

	public void onClick(Widget sender) {
		
		if(sender instanceof Button){
			Button clickedButton = ((Button) sender);
			if(clickedButton.getText().equals("Submit"))
			{
				HashMap<String, String> fields = log.getFields();
				if(validateFields(fields)){
					submit(fields);
				}
			}
		}	
		else if(sender instanceof HTML)
		{
			HTML html = ((HTML)sender);
			if(html.getText().endsWith("Register!"))
			{
				PanelMap.showPanel(log, PanelMap.getPanel("Register"));
			}
		}
	}

	public void onKeyDown(Widget sender, char keyCode, int modifiers) {
	}


	public void onKeyPress(Widget sender, char keyCode, int modifiers) {
		if (keyCode == KeyboardListener.KEY_ENTER){
			HashMap<String, String> fields = log.getFields();
			if(validateFields(fields)){
				submit(fields);
			}
		}
	}

	public void onKeyUp(Widget sender, char keyCode, int modifiers) {
	}
	
	private boolean validateFields(HashMap<String, String> fields){
		boolean retVal = true;
		String failMsg = "";
		
		//user name must be at least 4 characters and can contain numbers or letters
		if(!fields.get("username").matches("[A-Z,a-z,0-9]{4,}")){
			failMsg += "Invalid username.\n";
			retVal = false;
		}
		
		//password contains characters from ascii 33(!) to 126(~)
		if(!fields.get("password").matches("[!-~]+")){
			failMsg += "Invalid password.\n";
			retVal = false;
		}
		
		if(!failMsg.equals("")){
			MessageBox.showMessageDialog("Login", failMsg);
		}
		
		return retVal;
	}
	
	private void submit(final HashMap<String, String> fields){

		final AsyncCallback<SimpleUser> callback = new AsyncCallback<SimpleUser>()
		{			
			public void onSuccess(SimpleUser result)
			{
				if(result != null) // Login successful
				{
					// Set the email address to verified
					AsyncCallback<Boolean> callbackVerified = new AsyncCallback<Boolean>()
					{
						public void onSuccess(Boolean result)
						{
							if(!result)
							{
								System.out.println("Could not verify the users email address!");
							}
						}

						public void onFailure(Throwable ex)
						{
							Window.alert(ex.getMessage());
						}
					};
					
					Server.getInstance().getServer().setVerified(result.username, true, callbackVerified);
					
					log.getSession().setUser(result.username);	
					PanelMap.showPanel(log, PanelMap.getPanel("UserHome"));
				}
				else MessageBox.showMessageDialog("Error!", "Username/Password combination did not match! Please try again.");
			}

			public void onFailure(Throwable ex)
			{
				Window.alert(ex.getMessage());
			}
		};
		
		// Check if the user is locked out
		AsyncCallback<Boolean> callbackLocked = new AsyncCallback<Boolean>()
		{
			public void onSuccess(Boolean result)
			{
				if(!result)
				{
					Server.getInstance().getServer().authenticateUser(fields.get("username"), fields.get("password"), callback);
				}
				else
				{
					MessageBox.showMessageDialog("Error!", "You have been banned! Try again in a few days.");
				}
			}

			public void onFailure(Throwable ex)
			{
				Window.alert(ex.getMessage());
			}
		};
		
		Server.getInstance().getServer().getBanned(fields.get("username"), callbackLocked);
	}
	
}
